//
//Justin Swinney
//CPE 301
//DA 8
//The goal of the assignment is to modify the above codes to do the following
//
//1. Write a C program that will interface and MCP 4725 I2C DAC breakout board t
//generate at sine wave. Verify the sine wave in the oscilloscope. Connect a
//potentiometer to an analog port and vary the frequency based on the analog value.
//

#define F_CPU 8000000
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <E:\School\Spring 14'\DA8\DA8\DA8\values.h>

//Variables
unsigned int data; //variable to store the value from the look up table
unsigned int value; //stores the temp value before generating sine wave
unsigned int result; //sends the final result to the DAC chip
unsigned char outputDAC = 0; //Output value for DAC
unsigned char phase = 0; //Phase of the sine wave
unsigned char cycles=0;	//Number of cycles that have occurred since the last transition
unsigned char cycleCount = 20; //When the timer interrupts the number of cycles to send.


unsigned char wait()
{
	while(!(TWCR & (1<<TWINT))); //waits for it to get done
	return (TWSR & 0xF8);
}
unsigned char twi_send(unsigned char data)
{
	TWDR = data; // saves data to TWDR
	TWCR = 0x84; //Enables 2-wire Serial Interface
	return wait(); //Wait for TWI to finish.
}

void i2cSendStart()
{
	TWCR = 0xA4; //Enables 2-wire Serial Interface
	if(twi_send(0xC0)!=0x18) 
	return;
}

void i2cSendStop()
{
	TWCR = 0x94; //Disables 2-wire Serial Interface
	if(twi_send(0xF0)!=0x28) 
	return;
}

//Setting up AD Settings
void AD_setup()
{
	ADCSRA = 0xDF; //128 prescaler
	ADCSRB = 0x06; //timer1 overflow
	ADMUX = 0xC0; //ADC0, AREF
}

void timer_setup()
{
	TCCR1A = 0x00;
	TCCR1B = 0x0C; //no prescaler, normal op
	TIMSK1 = 0x02; //compare A Match int enabled
	OCR1A = 250;
}

void DAC(unsigned char data1, unsigned char data2)
{
	if(twi_send(data1&0xF)!=0x28)
	return;
	if(twi_send(data2)!=0x28)
	return;
}

ISR(TIMER1_COMPA_vect)
{
	while(cycles > data);
	{
		result = value;
		if (phase == 0)
			value = data + 10;
		else if (phase == 1)
			value = data - 10;
		else
			value = data + 25;
		outputDAC = value;
		}
	cli();
	if(!(ADCSRA & (1<<ADSC)))
	{
		cycleCount = 8+(ADC>>4);	//Sets the number of cycles to increment so the frequency varies.
		AD_setup();
	}

	value = (LUtable[phase]);		//Read from the inverse sine and adjust it with the phase.
	if(cycleCount < data && cycles < data)
		cycles = cycleCount + data;
	else
	{
		cycles =  cycleCount + data + phase;
		phase = (phase+1);
		data = (LUtable[(phase-1)]);
	}	
}

int main(void)
{
	AD_setup(); //initialize AD conversion
	timer_setup(); //set up timer 1
	sei(); //set global interrupts
	TWBR = TWSR = 0; // initializes the bit rate reg, status reg
	i2cSendStart();	// initiates conversion
	while(1)
	{													
		cli(); // clears interrupts
		value = outputDAC; //final value
		sei(); //set global interrupts
		DAC(0xCA, 0xA5);	//Write to the MCP4725.
	}
}